Fixed issues with "hierarchy-changed" signal.
authorTristan Van Berkom <tristan.van.berkom@gmail.com>
Fri, 24 Dec 2010 03:01:43 +0000 (12:01 +0900)
committerTristan Van Berkom <tristan.van.berkom@gmail.com>
Thu, 6 Jan 2011 05:39:40 +0000 (14:39 +0900)
GtkFileChooserDefault watches the toplevel and montitors "set-focus"
signal on it... however the connection needs to be remade when the
GtkFileChooserDialog is in an embedded toplevel.

Measure's taken: GtkWindow propagates hierarchy changes when
_gtk_window_set_is_toplevel() is called, gtk_widget_unparent()
unsets the widget's parent window earlier in the function so that
the possible hierarchy change is still able to properly access the hierarchy.

GtkFileChooserDefault checks if the "new" toplevel is indeed
gtk_widget_is_toplevel() but not the old one, GtkRange has been
updated to use gtk_widget_is_toplevel() inside it's hierarhcy_changed
vfunc, other classes already do this properly.

gtk/gtkfilechooserdefault.c
gtk/gtkrange.c
gtk/gtkwidget.c
gtk/gtkwindow.c

index c9eef75a5ad6c9a2e50027f8ddc2f6efb9f8f337..b99348aa4346234c4616e974ce048289a70eca22 100644 (file)
@@ -5599,7 +5599,7 @@ gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget,
     g_assert (impl->toplevel_set_focus_id == 0);
 
   toplevel = gtk_widget_get_toplevel (widget);
-  if (GTK_IS_WINDOW (toplevel))
+  if (gtk_widget_is_toplevel (toplevel))
     {
       impl->toplevel_set_focus_id = g_signal_connect (toplevel, "set-focus",
                                                      G_CALLBACK (toplevel_set_focus_cb), impl);
index 678a2dd2e43a957c98d47674d6587821c7f93fe7..4c8d4289df6668c8fa5150cafc679cece31fb1fc 100644 (file)
@@ -1660,7 +1660,7 @@ gtk_range_hierarchy_changed (GtkWidget *widget,
                                           G_CALLBACK (resize_grip_visible_changed),
                                           widget);
   window = gtk_widget_get_toplevel (widget);
-  if (GTK_IS_WINDOW (window))
+  if (gtk_widget_is_toplevel (window))
     g_signal_connect (window, "notify::resize-grip-visible",
                       G_CALLBACK (resize_grip_visible_changed), widget);
 }
index 9aa08658b251a4af82a4f523165f7fb4556c4235..20a268b8f9ed517d095ebb01a6c5b5dec5f592d9 100644 (file)
@@ -3714,9 +3714,17 @@ gtk_widget_unparent (GtkWidget *widget)
   g_object_freeze_notify (G_OBJECT (widget));
   nqueue = g_object_notify_queue_freeze (G_OBJECT (widget), _gtk_widget_child_property_notify_context);
 
+  /* Need to unset the parent window early, this can result in 
+   * an additional "hierarchy-changed" propagation if we are removing
+   * a parented GtkWindow from the hierarchy.
+   */
+  gtk_widget_set_parent_window (widget, NULL);
+
   toplevel = gtk_widget_get_toplevel (widget);
   if (gtk_widget_is_toplevel (toplevel))
     _gtk_window_unset_focus_and_default (GTK_WINDOW (toplevel), widget);
+  else
+    toplevel = NULL;
 
   if (gtk_container_get_focus_child (GTK_CONTAINER (priv->parent)) == widget)
     gtk_container_set_focus_child (GTK_CONTAINER (priv->parent), NULL);
@@ -3755,7 +3763,6 @@ gtk_widget_unparent (GtkWidget *widget)
 
   old_parent = priv->parent;
   priv->parent = NULL;
-  gtk_widget_set_parent_window (widget, NULL);
 
   /* parent may no longer expand if the removed
    * child was expand=TRUE and could therefore
index 477cccd6aca4a39d673d2934b6926cbe9653033d..60693ffdc1789ac1356d975e61d1d7a95d0224be 100644 (file)
@@ -9221,6 +9221,7 @@ _gtk_window_set_is_toplevel (GtkWindow *window,
                             gboolean   is_toplevel)
 {
   GtkWidget *widget;
+  GtkWidget *toplevel;
 
   widget = GTK_WIDGET (window);
 
@@ -9234,6 +9235,12 @@ _gtk_window_set_is_toplevel (GtkWindow *window,
 
   if (is_toplevel)
     {
+      toplevel = gtk_widget_get_toplevel (widget);
+      if (!gtk_widget_is_toplevel (toplevel))
+       toplevel = NULL;
+
+      _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
+
       _gtk_widget_set_is_toplevel (widget, TRUE);
       toplevel_list = g_slist_prepend (toplevel_list, window);
     }
@@ -9241,6 +9248,8 @@ _gtk_window_set_is_toplevel (GtkWindow *window,
     {
       _gtk_widget_set_is_toplevel (widget, FALSE);
       toplevel_list = g_slist_remove (toplevel_list, window);
+
+      _gtk_widget_propagate_hierarchy_changed (widget, widget);
     }
 }